package GameObjects;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Shape;
import java.awt.event.ActionListener;
import java.awt.geom.Area;

import Enviroment.Bounds;
import Enviroment.QuadItem;
import GUI.BottomPanel;
import GameObjects.Instances.Instances;
import GameObjects.Physics.Position;
import GameObjects.Ships.Ship;
import GameObjects.Ships.Weapon.Weapon;
import GameObjects.Ships.Weapon.Bullets.Bullet;

public abstract class InstanceObject extends QuadItem
{	
	protected final Instances instances;
	
	protected Position position;
	
	public InstanceObject(Instances instances, Position position)
	{
		this.instances = instances;
		this.position = position;
	}
	
	public void render(Graphics2D g)
	{
		Graphics2D g2d = (Graphics2D)g.create();
		//g2d.clip(bounds);
		
		//commented out for now until images are supplied
		//instances.render(g2d, x, y, theta);
		
		//currently use the bounds as the display
		//should be fine
		Shape bounds = transformedBounds();
		g2d.setColor(Color.RED);
		g2d.draw(bounds);
		//g2d.drawOval((int)position.x()-5, (int)position.y()-5, 10, 10);
		g2d.setColor(Color.BLACK);
	}
		
	protected void collided(InstanceObject other)
	{
		if(other instanceof Ship)
			collided((Ship)other);
		else if(other instanceof Bullet)
			collided((Bullet)other);
		else if(other instanceof Weapon)
			collided((Weapon)other);
		//TODO extend for other object types
	}
	
	protected abstract void collided(Ship other);
	
	protected abstract void collided(Bullet other);
	
	protected abstract void collided(Weapon other);
	
	//TODO add stubs for extra game object types
	
	public void hasCollided(QuadItem item)
	{
		if(item instanceof InstanceObject)
			hasCollided((InstanceObject)item);
	}
	
	public void hasCollided(InstanceObject other)
	{
		Shape bounds = transformedBounds();
		Area a = new Area(bounds);
		Shape otherBounds = other.transformedBounds();
		Area b = new Area(otherBounds);
		a.intersect(b);
		if(!a.isEmpty())
			collided(other);
	}

	private Shape transformedBounds()
	{
		return instances.transformInstance(position.x(), position.y(), position.theta());
	}
	
	public InstanceObject hasClicked(Point point)
	{
		if(transformedBounds().contains(point))
			return this;
		return null;
	}
	
	public abstract void setPanel(ActionListener actionListener, BottomPanel panel);
	
	public boolean tickObject()
	{
		instances.tick();
		return tick();
	}
	
	public abstract boolean tick();
	
	public Bounds getBounds()
	{
		Bounds bound = new Bounds((int)position.x(), (int)position.y(), (int)instances.width(), (int)instances.height());
		return bound;
	}
}
